package com.google.hackathon.game.shriko.core;

import static playn.core.PlayN.*;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.World;

import playn.core.GroupLayer;
import playn.core.Image;
import playn.core.ImageLayer;
import playn.core.Pointer;

public class Stage implements State {
  private final Random random = new Random();
  private Image bgImage;
  private List<Ghost> ghosts = new ArrayList<Ghost>();
  private GroupLayer ghostsLayer;

  private static final float WIDTH = 480.0f;
  private static final float HEIGHT = 800.0f;
  private Image ghostImage;
  private Image fireImage;

  private Image syurikenImage;
  private GroupLayer syurikensLayer;

  private List<Syuriken> syurikens = new ArrayList<Syuriken>();

  private Ninja ninja;
  private World world;

  public Stage() {
    graphics().setSize(480, 800);
    // create and add background image layer
    bgImage = assetManager().getImage("images/stage_bg.png");
    ImageLayer bgLayer = graphics().createImageLayer(bgImage);
    bgLayer.setWidth(graphics().width());
    bgLayer.setHeight(graphics().height());
    graphics().rootLayer().add(bgLayer);

    syurikenImage = assetManager().getImage("images/syuriken.png");
    syurikensLayer = graphics().createGroupLayer();
    graphics().rootLayer().add(syurikensLayer);

    ghostsLayer = graphics().createGroupLayer();
    graphics().rootLayer().add(ghostsLayer);
    ghostImage = assetManager().getImage("images/obake.png");
    fireImage = assetManager().getImage("images/hinotama.png");
    pointer().setListener(new Pointer.Adapter() {
      @Override
      public void onPointerEnd(Pointer.Event event) {
        if (ninja.y - 100 > event.y()) {
          // 忍者より前の場合は手裏剣を投げる
          Syuriken syuriken = new Syuriken(world, syurikenImage, event.x(),
              event.y());
          syurikens.add(syuriken);
          syurikensLayer.add(syuriken.getLayer());
          // 投げてる間は停まる
          ninja.throwing = 100;
        } else {
          // 忍者より下の場合は移動
          ninja.moveToX = event.x();
        }
      }
    });

    ninja = new Ninja();
    ninja.init();
    initPhysics();
  }

  private void addNewGhost() {
    final float radius = (random.nextFloat() + 0.5f) * 100.0f;
    final float x = random.nextFloat() * WIDTH;
    final float y = random.nextFloat() * HEIGHT * 0.5f;
    final Image img = random.nextBoolean() ? ghostImage : fireImage;
    final Ghost ghost = new Ghost(world, img, radius, x, y);
    ghosts.add(ghost);
    ghostsLayer.add(ghost.getLayer());
  }

  private void gcGhost() {
    final Iterator<Ghost> it = ghosts.iterator();
    while (it.hasNext()) {
      final Ghost ghost = it.next();
      if (ghost.getY() > HEIGHT) {
        ghost.setInvisible();
        it.remove();
        System.out.println("ghost removed");
      }
    }
  }

  @Override
  public void update(float delta) {
    world.step(0.033f, 10, 10);
    for (Syuriken syuriken : syurikens) {
      syuriken.update(delta);
    }

    ninja.update(delta);
  }

  @Override
  public void paint(float delta) {
    // tekitou
    if (random.nextDouble() > 0.99) {
      addNewGhost();
      gcGhost();
    }
    // the background automatically paints itself, so no need to do anything
    // here!
    for (Ghost ghost : ghosts) {
      ghost.paint(delta);
    }
  }

  private void initPhysics() {
    Vec2 gravity = new Vec2(0.0f, 10.0f);
    world = new World(gravity, true);
    world.setWarmStarting(true);
    world.setAutoClearForces(true);
  }

  @Override
  public boolean hasNextState() {
    return false;
  }

  @Override
  public State nextState() {
    return null;
  }
}
